package fnic.prehand.action;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;

import fnic.jsontrans.DeviceId;
import fnic.jsontrans.interfacer.*;
import fnic.jsontrans.modesearch.*;
import fnic.modesearch.SimpleIFSearch;
import fnic.prehand.common.AgentConfig;
import fnic.prehand.common.JacksonFormatService;


public class SearchFromESServlet extends HttpServlet {
	private static final Logger LOG = Logger.getLogger(SearchFromESServlet.class);
	private static final int phoneHistorySize = 5;
	private static final JacksonFormatService jsonInstance = JacksonFormatService.getInstance();
	private static final AgentConfig config = AgentConfig.getInstance();

	private SimpleIFSearch simsearch;
	
	public SearchFromESServlet(String idx, String type){
		simsearch = new SimpleIFSearch(idx, type);
	}
	
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		// 手机检索
		String type = request.getParameter("probetype");
		if (type != null && type.equals("2")) {
			InputStreamReader isr = null;
			BufferedReader streamReader = null;
			StringBuilder probedata = null;
			String httpbody;
			String[] strIds;
//			ObjectMapper objectMapper = new ObjectMapper();
			int size = 0;
			// Map<String,String> mutiindexmap= new HashMap<String,String>();
			ArrayList<PhoneSearch2Web> list = new ArrayList<PhoneSearch2Web>();
			try {
				// 获取post body内容，加载到probedata中
				String tempString;
				isr = new InputStreamReader(request.getInputStream(), "UTF-8");
				streamReader = new BufferedReader(isr);
				probedata = new StringBuilder();
				while ((tempString = streamReader.readLine()) != null) {
					probedata.append(tempString);
				}
				httpbody = probedata.toString();
//				System.out.println("src:" + httpbody);
//				PhnSearchIds objIds = objectMapper.readValue(httpbody,
//						PhnSearchIds.class);
				PhnSearchIds objIds = (PhnSearchIds)jsonInstance.String2Obj(httpbody, "fnic.jsontrans.interfacer.PhnSearchIds");
				if(objIds == null){
					LOG.error("phone search ids parse error,id = null");
					response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
					if (streamReader != null) {
						streamReader.close();
					}
					if (isr != null) {
						isr.close();
					}
					return;
				}
				strIds = objIds.getIndexids();
				size = strIds.length;
				String[] srcDoc = simsearch.getMtlId(strIds, size);
				if (srcDoc != null) {
					for (int i = 0; i < size; i++) {
						// mutiindexmap.put(strIds[i],srcDoc[i]);
						list.add(new PhoneSearch2Web(strIds[i],srcDoc[i]));
					}
				}
				// 建立输出流，并写入数据
				response.setContentType("application/json;charset=utf-8");
				response.setStatus(HttpServletResponse.SC_OK);
				PrintWriter pw = response.getWriter();
//				JSONArray jo = JSONArray.fromObject(list);
//				pw.println(jo);
				String res = jsonInstance.Obj2String(list);
				pw.println(res);
				// return;
			} catch (Exception e) {
				//ES检索失败--手机批量获取ids失败
				LOG.warn("probe data parse exception - " + e.getMessage());
				response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			} finally {
				if (streamReader != null) {
					streamReader.close();
				}
				if (isr != null) {
					isr.close();
				}
			}
		} else {
			// 此方法主要负责监听web端发起的检索请求，并将检索结果加入QueryQueue
			// 此线程为检索线程，为确保检索的实时性和正确性，应采用阻塞形式等待检索结果的返回
			String[] values = request.getParameterValues(DeviceId.COND_WEB_ID);
			if (values == null || values.length != 1) {
				response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
				LOG.info("invalid request...");
				return;
			}

			LOG.info("do search ...");
			// 获取request请求中queuestring部分内容
			String indexid = request.getParameter("indexId");
			PrintWriter pw = null;
			try {
				String searchresult = simsearch.idGet(indexid);
				response.setContentType("application/json;charset=utf-8");
				response.setStatus(HttpServletResponse.SC_OK);
				pw = response.getWriter();
				pw.println(searchresult);
				pw.close();
			} catch (Exception e) {
				//ES检索失败--根据id获取源数据失败
				LOG.error("Parse entity exception: " + e.getMessage());
				response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			}
		}
	}

	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		LOG.info("do get ..."+request.getRequestURI()+request.getQueryString());

		double curdelay = 0.0;
		int isNetquality = 0;
		int isCallquality = 0;
		String probeid = null;
		boolean friendscomp = false;
		
		//手机历史数据获取
//		int probeId = 0;
//		int historySize = 0;
//		int historyNum = 0;

		try {
			if (request.getParameter("netQuality") != null) {
				isNetquality = Integer.parseInt(request.getParameter("netQuality"));
			}
			if (request.getParameter("callQuality") != null) {
				isCallquality = Integer.parseInt(request.getParameter("callQuality"));
			}
			if (request.getParameter("curDelayTime") != null) {
				curdelay = Double.parseDouble(request.getParameter("curDelayTime"));
			}
			if (request.getParameter("probeId") != null) {
				probeid = request.getParameter("probeId");
			}
			if (request.getParameter("compare") != null) {
				friendscomp = Boolean.parseBoolean(request.getParameter("compare"));
			}
			
			//手机历史记录获取
//			if(request.getParameter("probeId") != null){
//				probeId = Integer.parseInt(request
//						.getParameter("probeId"));
//			}
//			if(request.getParameter("historyBulkSize") != null){
//				historySize = Integer.parseInt(request
//						.getParameter("historyBulkSize"));
//			}
//			if(request.getParameter("historyBulkNum") != null){
//				historyNum = Integer.parseInt(request
//						.getParameter("historyBulkNum"));
//			}
		} catch (NumberFormatException e) {
			//ES检索失败--手机请求URL不合法
//			e.printStackTrace();
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			LOG.info("parse params Exception...");
			return;
		} catch (Exception e) {
//			e.printStackTrace();
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			LOG.info("parse params Exception...");
			return;
		}

		String ret = null;
//		if(probeId!=0 && historySize!=0 && historyNum!=0){
//			PhoneHistory historySrc=getPhoneHistory(probeId, historySize, historyNum);
//			if(historySrc!=null){
////				ret = parseObj2Json(historySrc);
//				LOG.info("succeed");
//				ret = JSONObject.fromObject(historySrc).toString();
//			}
//
//		}else{
			TermFacetOutput netTermFacet;
			TermFacetOutput callTermFacet;
			RangeFacetOutput pingRangeFacet;
			StaticalFacetOutput pingStaticFacet;
			PhoneSearch2Phone phoneRes = new PhoneSearch2Phone();
			/*
			 * 统计网络质量
			 */
			if (isNetquality == 1) {
				// 获取Field = netquality
				String field = "netquality";
				netTermFacet = simsearch.termFacet(field);
				if(netTermFacet!=null){
					long totalsize = netTermFacet.getTotal();
					Iterator<TermFacetOutput.TermCount> iterator = netTermFacet
							.getItemList().iterator();
					while (iterator.hasNext()) {
						phoneRes.addNetRate((double) iterator.next().getCount()
								/ totalsize);
					}
				}
			}

			/*
			 * 统计童话质量
			 */
			if (isCallquality == 1) {
				// 获取Field = callquality
				String field = "callquality";
				callTermFacet = simsearch.termFacet(field);
				if(callTermFacet!=null){
					long totalsize = callTermFacet.getTotal();
					Iterator<TermFacetOutput.TermCount> iterator = callTermFacet
							.getItemList().iterator();
					while (iterator.hasNext()) {
						phoneRes.addCallRate((double) iterator.next().getCount()
								/ totalsize);
					}
				}
			}

			/*
			 * 统计全局PING时延和战胜率
			 */
			if (!(Math.abs(curdelay - 0.0) < 0.000001)) {
				String field = "pingdelayavg";
				pingRangeFacet = simsearch.rangeFacet(curdelay, field);
				// beat over
				double beatover = 0.0;
				if(pingRangeFacet!=null){
					int rangeSize = pingRangeFacet.getRangeItemList().size();
					if (rangeSize == 2) {
						long slowcount = pingRangeFacet.getRangeItemList().get(1)
								.getCount();
						long totalcount = pingRangeFacet.getAllcount();
						beatover = (double) slowcount / totalcount;
						phoneRes.setBeatover(beatover);
					} else {
						LOG.error("Range Facet error!");
					}
				}

				// avg delay
				pingStaticFacet = simsearch.staticalFacet(field);
				if(pingStaticFacet!=null){
					phoneRes.setGlobalAvgPingDelay(pingStaticFacet.getMean());
				}
			}

			if(probeid!=null){
//				fndTraces = new PhnFriendsTrace[2];
//				fndTraces[0] = new PhnFriendsTrace();
//				getNearbyTrace(31.934364, 118.792732, 0);
//				
//				fndTraces[1] = new PhnFriendsTrace();
//				getNearbyTrace(31.934373, 118.792739, 1);
//				getUserMeasureTrace(imsi, friendscomp);
				if(friendscomp){
					ret = simsearch.getUserNearbyTrace(probeid);

				}else{
					ret = simsearch.getUserTrace(probeid);
				}
			}else{
				ret = jsonInstance.Obj2String(phoneRes);
			}
//		}

		if(ret!=null){
			PrintWriter pw = null;
			try {
				response.setContentType("application/json;charset=utf-8");
				response.setStatus(HttpServletResponse.SC_OK);
				pw = response.getWriter();
				pw.println(ret);
				pw.close();
			} catch (Exception e) {
				//ES检索失败--ES内部原因GET方法，给手机返回响应失败
				LOG.error("Parse entity exception: " + e.getMessage());
				response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			}
		}else{
			//ES检索失败--检索结果转换json失败
			LOG.error("GET NONE result phone statics or history!");
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
		}

	}


	


}
